package com.cennavi.minemap.controller;

import java.io.File;
import java.util.Enumeration;
import java.util.List;

import javax.servlet.http.HttpServletRequest;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.cennavi.minemap.bean.DataBean;
import com.cennavi.minemap.bean.MessageBean;
import com.cennavi.minemap.bean.RoleBean;
import com.cennavi.minemap.bean.UniqueVerifyBean;
import com.cennavi.minemap.bean.UserBean;
import com.cennavi.minemap.service.MailService;
import com.cennavi.minemap.service.UserService;
import com.cennavi.minemap.util.DESUtil;
import com.cennavi.minemap.util.DateTimeUtil;
import com.cennavi.minemap.util.HttpClientUtil;
import com.cennavi.minemap.util.ShellUtil;
import com.cennavi.minemap.util.StringUtil;
import com.fasterxml.jackson.databind.ObjectMapper;

@RestController
@ComponentScan(basePackages = { "com.cennavi.minemap.service" })
@PropertySource(value = { "classpath:application.properties" })
@RequestMapping("/service/user")
public class UserController {

	@Value("${spring.auth.expiry.file}")
	private String expiryFile;

	@Value("${spring.mail.username}")
	private String fromUser;

	@Value("${spring.minemap.verification.minutes}")
	private int minutes;

	@Value("${minemap.tencent.verification.url}")
	private String tecentVerifUrl;

	ObjectMapper objectMapper = new ObjectMapper();

	@Autowired
	private UserService userService;

	@Autowired
	private MailService mailService;

	@RequestMapping(value = "/test1", method = RequestMethod.GET)
	public @ResponseBody String test1() throws Exception {
		return tecentVerifUrl;
	}
	
	
	@RequestMapping(value = "/login", method = RequestMethod.POST)
	public @ResponseBody MessageBean login(@RequestBody String json) throws Exception {
		UserBean userBean = objectMapper.readValue(json, UserBean.class);
		MessageBean messageBean = new MessageBean();
		List<UserBean> list = userService.login(userBean);
		if (list.size() <= 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("username or password error");
		} else {
			DataBean<UserBean> dataBean = new DataBean<UserBean>();
			messageBean.setErrcode(0);

			dataBean.setTotal(list.size());
			dataBean.setRows(list);
			messageBean.setData(dataBean);
		}
		return messageBean;
	}

	@RequestMapping(value = "/register", method = RequestMethod.POST)
	public @ResponseBody MessageBean register(@RequestBody String json) throws Exception {
		UserBean userBean = objectMapper.readValue(json, UserBean.class);
		MessageBean messageBean = new MessageBean();
		List<UserBean> list = userService.register(userBean);
		if (list.size() < 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("register error");
		} else {
			DataBean<UserBean> dataBean = new DataBean<UserBean>();
			messageBean.setErrcode(0);

			dataBean.setTotal(list.size());
			dataBean.setRows(list);
			messageBean.setData(dataBean);
		}
		return messageBean;
	}

	@RequestMapping(value = "/update", method = RequestMethod.POST)
	public @ResponseBody MessageBean update(@RequestBody String json) throws Exception {
		UserBean userBean = objectMapper.readValue(json, UserBean.class);
		MessageBean messageBean = new MessageBean();
		List<UserBean> list = userService.update(userBean);
		if (list.size() < 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("user update error");
		} else {
			DataBean<UserBean> dataBean = new DataBean<UserBean>();
			messageBean.setErrcode(0);

			dataBean.setTotal(list.size());
			dataBean.setRows(list);
			messageBean.setData(dataBean);
		}
		return messageBean;
	}

	@RequestMapping("/{id}")
	public @ResponseBody MessageBean detail(@PathVariable int id) {
		MessageBean messageBean = new MessageBean();
		List<UserBean> list = userService.queryById(id);
		if (list.size() < 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("query error");
		} else {
			DataBean<UserBean> dataBean = new DataBean<UserBean>();
			messageBean.setErrcode(0);
			dataBean.setTotal(list.size());
			dataBean.setRows(list);
			messageBean.setData(dataBean);
		}
		return messageBean;
	}

	@RequestMapping("/expiry")
	public @ResponseBody MessageBean getExpire() throws Exception {
		MessageBean messageBean = new MessageBean();
		// File f = new
		// File(ExpirtyInterceptor.class.getResource(expiryFile).getFile());
		File f = new File(expiryFile);
		String dmidecode = ShellUtil.shell("dmidecode -s system-serial-number");
		while (dmidecode.length() < 16) {
			dmidecode = "0" + dmidecode;
		}

		String expiry = DESUtil.readDecryptFile(f.getPath());
		String expiryDate = DESUtil.decrypt(expiry, dmidecode);
		messageBean.setErrcode(0);
		JSONObject data = new JSONObject();
		data.put("expiry", expiryDate);
		messageBean.setData(data);
		return messageBean;
	}

	@RequestMapping("/unique")
	public @ResponseBody MessageBean uniqueVerify(@RequestBody String json) throws Exception {
		UniqueVerifyBean uniqueVerifyBean = objectMapper.readValue(json, UniqueVerifyBean.class);
		MessageBean messageBean = new MessageBean();
		int count = userService.uniqueVerify(uniqueVerifyBean.getAttribute(), uniqueVerifyBean.getValue());
		if (count > 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg(uniqueVerifyBean.getAttribute() + " exists");
		} else {
			messageBean.setErrcode(0);
		}
		return messageBean;
	}

	@RequestMapping("/sendVer")
	public @ResponseBody MessageBean sendVer(@RequestParam("mail") String mail) throws Exception {
		MessageBean messageBean = new MessageBean();

		String vCode = StringUtil.getRandNum(100000, 999999);
		String vDate = DateTimeUtil.getXMinuteAfter(minutes);

		int exist = userService.queryByMail(mail);
		if (exist == 0) {
			messageBean.setErrcode(-2);
			messageBean.setErrmsg("mailbox not register");
			return messageBean;
		}

		int status = userService.updateVerification(mail, vCode, vDate);
		if (status < 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("send verification code error");
		} else {
			String subject = "minemap验证码";
			String content = "验证码为" + vCode + "，有效期为" + minutes + "分钟。";
			mailService.sendSimpleMail(fromUser, mail, subject, content);
			messageBean.setErrcode(0);
		}
		return messageBean;
	}

	@RequestMapping(value = "/verification", method = RequestMethod.POST)
	public @ResponseBody MessageBean verification(@RequestBody String json) {

		JSONObject input = JSONObject.parseObject(json);
		String mail = input.getString("mail");
		String code = input.getString("code");
		MessageBean messageBean = new MessageBean();

		String now = DateTimeUtil.getNow();
		List<UserBean> list = userService.queryByVCode(mail, code, now);
		if (list.size() <= 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("verification code error or send timeout");
		} else {
			DataBean<UserBean> dataBean = new DataBean<UserBean>();
			messageBean.setErrcode(0);
			dataBean.setTotal(list.size());
			dataBean.setRows(list);
			messageBean.setData(dataBean);
		}
		return messageBean;
	}

	@RequestMapping(value = "/updatePwd", method = RequestMethod.POST)
	public @ResponseBody MessageBean updatePassword(@RequestBody String json) throws Exception {
		UserBean userBean = objectMapper.readValue(json, UserBean.class);

		MessageBean messageBean = new MessageBean();
		List<UserBean> list = userService.updatePassword(userBean);
		if (list.size() <= 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("update password error");
		} else {
			DataBean<UserBean> dataBean = new DataBean<UserBean>();
			messageBean.setErrcode(0);
			dataBean.setTotal(list.size());
			dataBean.setRows(list);
			messageBean.setData(dataBean);
		}
		return messageBean;
	}

	@RequestMapping(value = "/mailboxVeri", method = RequestMethod.POST)
	public @ResponseBody MessageBean mailboxVeri(@RequestBody String json) throws Exception {
		UserBean userBean = objectMapper.readValue(json, UserBean.class);

		MessageBean messageBean = new MessageBean();
		List<UserBean> list = userService.mailboxVeri(userBean);
		if (list.size() <= 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("mailbox verification error");
		} else {
			DataBean<UserBean> dataBean = new DataBean<UserBean>();
			messageBean.setErrcode(0);
			dataBean.setTotal(list.size());
			dataBean.setRows(list);
			messageBean.setData(dataBean);
		}
		return messageBean;
	}

	@RequestMapping("/role/{userId}")
	public @ResponseBody MessageBean queryRoleByUserId(@PathVariable int userId) {
		MessageBean messageBean = new MessageBean();
		List<RoleBean> list = userService.queryRoleByUserId(userId);
		if (list.size() < 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("query role error");
		} else {
			DataBean<RoleBean> dataBean = new DataBean<RoleBean>();
			messageBean.setErrcode(0);
			dataBean.setTotal(list.size());
			dataBean.setRows(list);
			messageBean.setData(dataBean);
		}
		return messageBean;
	}

	@RequestMapping(value = "/tencent/register", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
	public @ResponseBody MessageBean tencentRegister(@RequestBody String text) throws Exception {
		JSONObject json = JSONObject.parseObject(text);
		MessageBean messageBean = new MessageBean();

		UserBean userBean = new UserBean();
		userBean.setUsername(json.getString("username"));
		userBean.setPassword(json.getString("password"));
		try {
			List<UserBean> list = userService.register(userBean);
			if (list.size() < 0) {
				messageBean.setErrcode(-1);
				messageBean.setErrmsg("register error");
			} else {
				messageBean.setErrcode(0);
				Integer id = list.get(0).getId();
				json.put("id", id);
				messageBean.setData(json);
			}
		} catch (DuplicateKeyException e) {
			messageBean.setErrcode(-2);
			messageBean.setErrmsg("用户名已存在。");
		} catch (Exception e) {
			messageBean.setErrcode(-3);
			messageBean.setErrmsg("插入数据错误。");
		}
		return messageBean;
	}

	@RequestMapping(value = "/tencent/login", method = RequestMethod.POST)
	public @ResponseBody MessageBean tencentLogin(@RequestBody String text) throws Exception {
		JSONObject json = JSONObject.parseObject(text);
		String loginName = json.getString("LoginName");
		MessageBean messageBean = new MessageBean();
		List<UserBean> list = userService.tencentLogin(loginName);
		if (list.size() <= 0) {
			messageBean.setErrcode(-1);
			messageBean.setErrmsg("username not exists");
		} else {
			DataBean<UserBean> dataBean = new DataBean<UserBean>();
			messageBean.setErrcode(0);

			dataBean.setTotal(list.size());
			dataBean.setRows(list);
			messageBean.setData(dataBean);
		}
		return messageBean;
	}

	@RequestMapping(value = "/tencent/verification", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
	public @ResponseBody String tencentVerification(@RequestBody String text, HttpServletRequest request)
			throws Exception {
		JSONObject json = JSONObject.parseObject(text);
		json.put("Ip", getIpAddr(request));
		String response = "";
		try {
			Enumeration<String> names = request.getHeaderNames();
			System.out.println("header:");
			while (names.hasMoreElements()) {
				String name = (String) names.nextElement();
				System.out.println(name + ":" + request.getHeader(name));
			}
			System.out.println("url:" + tecentVerifUrl);
			System.out.println("json:" + json.toJSONString());
			response = HttpClientUtil.doPost(tecentVerifUrl, json);
			System.out.println("response:" + response);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return response;
	}

	public String getIpAddr(HttpServletRequest request) {
		String ip = request.getHeader("x-forwarded-for");
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getHeader("WL-Proxy-Client-IP");
		}
		if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) {
			ip = request.getRemoteAddr();
		}
		if (ip == null || ip.length() == 0) {
			return ip.split(",")[0];
		} else {
			return "127.0.0.1";
		}

	}
}
